package io.kiki.sba.registry.task;


import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class KeyedTask<T extends Runnable> implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(KeyedTask.class);
    @Getter
    final long createTime = System.currentTimeMillis();
    final Object key;
    @Getter
    final T runnable;

    @Getter
    volatile long startTime;
    @Getter
    volatile long endTime;
    volatile boolean success;
    volatile boolean canceled;

    KeyedTask(Object key, T runnable) {
        this.key = key;
        this.runnable = runnable;
    }

    public void cancel() {
        this.canceled = true;
    }

    @Override
    public void run() {
        try {
            this.startTime = System.currentTimeMillis();
            if (!canceled) {
                runnable.run();
            }
            this.success = true;
        } catch (TaskErrorSilenceException ignored) {
            logger.debug("failed to run task {}, {}", key, runnable);
        } catch (Throwable e) {
            logger.error("failed to run task {}, {}", key, runnable, e);
        } finally {
            this.endTime = System.currentTimeMillis();
        }
    }

    public boolean isFinished() {
        return this.endTime > 0;
    }

    public boolean isSuccess() {
        return isFinished() && success;
    }

    public boolean isFailed() {
        return isFinished() && !success;
    }

    public Object key() {
        return key;
    }

    public boolean isOverAfter(int intervalMs) {
        if (!isFinished()) {
            return false;
        }
        return canceled || System.currentTimeMillis() - endTime >= intervalMs;
    }


}
